package timeline.util;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import timeline.util.TimeLine.RunFinishResult;
import timeline.util.model.TaskModel;

public class TimeLineServer {
	private final static Logger logger = Logger.getLogger(TimeLineServer.class
			.getName());
	private ServerSocket server;
	private static String serverName;
	

	public void init(String serverName,final int port,int pool,int exec) throws IOException {
		System.out.println(""+this+" init!");
		new TimeLine.Builder().setPoolSize(pool,exec).commit();
		this.serverName = serverName;
		new Thread(new Runnable() {
			public void run() {
				try {
					server = new ServerSocket(port);
					while (true) {
						Socket socket = server.accept();
						invoke(socket);
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();
	}

	public void terminal() throws IOException {
		server.close();
	}

	private static void invoke(final Socket socket) throws IOException {
		new Thread(new Runnable() {
			public void run() {
				try {
					final ObjectInputStream is = new ObjectInputStream(
							new BufferedInputStream(socket.getInputStream()));
					final ObjectOutputStream os = new ObjectOutputStream(
							socket.getOutputStream());
					Object obj = is.readObject();
					TaskModel taskModel = (TaskModel) obj;
					Class<?> lib = new TimeLineClassLoader().myDefineClass(taskModel.ObjName, taskModel.data, 0, taskModel.data.length);
					Object libIns = lib.newInstance();
					new TimeLine.Builder().addLib(libIns).run(new RunFinishResult() {
						
						@Override
						public void onResult(ConcurrentHashMap<String, Object> map) {
							// TODO Auto-generated method stub
							map.put("ServerName",serverName );
							try {
								os.writeObject(map);
								os.flush();
							} catch (Exception e) {
								// TODO: handle exception
							}
							try {
								is.close();
							} catch (Exception ex) {
							}
							try {
								os.close();
							} catch (Exception ex) {
							}
							try {
								socket.close();
							} catch (Exception ex) {
							}
						}
					});
					
				} catch (IOException ex1) {
					logger.log(Level.SEVERE, null, ex1);
				} catch (ClassNotFoundException ex2) {
					logger.log(Level.SEVERE, null, ex2);
				}catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		}).start();
	}
}
